#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cassert>
#include <pthread.h>
#include <unistd.h>
#include <cstdlib>
#include <functional>
using namespace std;
#define num 1024
typedef function<void*(void*)> fun_t;
class Thread;

class Context
{
public:
    Context()
    :this_(nullptr)
    ,arg_(nullptr)
    {}
    ~Context()
    {}
    Thread* this_;
    void* arg_;
};
class Thread
{

private:
    pthread_t tid_;
    string name_;
    fun_t func_;
    void* arg_;

public:
    Thread(fun_t func,void* arg,int number)
    :func_(func)
    ,arg_(arg)
    {
        char buffer[num];
        snprintf(buffer,sizeof buffer,"thread-%d",number);
        name_ = buffer;


        Context* ctx = new Context();
        ctx->this_ = this;
        ctx->arg_  = arg_;
        int n = pthread_create(&tid_,nullptr,start_routine,ctx);
        assert(n == 0);
        (void)n;
    }
    static void* start_routine(void* args)
    {
        Context* ctx = static_cast<Context *>(args);
        void* ret = ctx->this_->run(ctx->arg_);
        delete ctx;
        return ret;
    }
    void* run(void* arg)
    {
        return func_(arg);
    }
    void join()
    {
       int n = pthread_join(tid_,nullptr);
       assert(n == 0);
       (void)n;
    }
    ~Thread()
    {}
};